/*
* Conditions Of Use
*
* This software was developed by employees of the Sigmatrix(Beijing) Corporation.
* This software is provided by sigmatrix as a service and is expressly
* provided "AS IS."  Sigmatrix MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY.  Sigmatrix does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
* Permission to use this software is contingent upon your acceptance
* of the terms of this agreement.
*
*/
package com.sigmatrix.h5.utils;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.sigmatrix.h5.entity.FirstLevelQRCode;
import com.sigmatrix.h5.entity.MultistageLevelQRCode;
import com.sigmatrix.h5.entity.QRCodeCompose;
import com.sigmatrix.h5.enums.MultistageLevelQRCodeStatusEnum;
import com.sigmatrix.h5.exception.ServiceException;


/**
 *@ClassName: QRCodeUtil
 *@Description: 码工具类
 *@author youjun
 *@date 2017年8月8日 下午4:31:12
 */
public class QRCodeUtil {
	
	/**logger record*/
	private static final Logger LOGGER = LoggerFactory.getLogger(QRCodeUtil.class);

	/**SHA-256算法*/
	private static final String SHA256 = "SHA-256";
	
	/**SHA-512算法*/
	@SuppressWarnings("unused")
	private static final String SHA512 = "SHA-512";
	
	/**
	 *@Title: conversionQRCode
	 *@Description: 转换传递的码
	 *@return String
	 *@author youjun
	 *@date 2017年8月8日 下午4:33:51
	 *@param qRCode
	 *@return
	 */
	public static String conversionQRCode(final String qRCode, final boolean isNeedConversion) {
		if(StringUtils.isNotBlank(qRCode)) {
			// ................转换过程
			String code = qRCode;
			if(isNeedConversion){
//				code = testGetFriendCode(qRCode);
				try {
					code = digestSHA256(splitCode(code).getCodeData());
				} catch (Exception e) {
					LOGGER.error("摘要码失败", e);
				}
			}
			return code;
		}
		return "";
	}
	
	/**
	 *@Title: testGetFriendCode
	 *@Description: 测试用的,测试数据形如：HTTP://TCC.SO/A/R*HF:2UAA1LW+Q.HGVCQL1?P=fl101
	 *@return String
	 *@author youjun
	 *@date 2017年8月8日 下午8:54:50
	 *@param qRCode
	 *@return
	 */
	public static String testGetFriendCode(final String qRCode) {
		final String[] codeArray = qRCode.split("=");
		return codeArray[1];
	}
	
	/**
	 *@Title: splitCode
	 *@Description: 将一个完整的码数据拆分
	 *@return QRCodeCompose
	 *@author liuzelei
	 *@date 2017年8月13日 下午4:02:51
	 *@param code
	 *@return
	 */
	public static QRCodeCompose splitCode(String code){
		if(StringUtils.isEmpty(code)){
			return new QRCodeCompose(code);
		}
		final QRCodeCompose qrCode = new QRCodeCompose();
		qrCode.setQrcode(code);
		
		int frist = code.lastIndexOf("/")+1;
		int second = code.indexOf("?");
		if(frist != -1){
			qrCode.setDomain(code.substring(0, frist));
		}
		if(frist != -1 && second == -1){
			qrCode.setCodeData(code.substring(frist));
		}else if(frist != -1 && second != -1){
			qrCode.setCodeData(code.substring(frist,second));
			qrCode.setArgument(code.substring(second));
		}
		return qrCode;
	}
	
	/**
	 *@Title: digestSHA256
	 *@Description: 码使用的SHA256算法,加密后为64位
	 *@return String
	 *@author youjun
	 *@date 2017年8月10日 上午1:37:03
	 *@param src 码
	 *@return
	 *@throws Exception
	 */
	public static String digestSHA256(final String src) throws Exception {
		return digestSHA(src, SHA256);
	}
		
	/**
	 * 
	 * @param src
	 * @param algorithmName it must be SHA-256 or SHA-512
	 * @return
	 * @throws Exception
	 */
	private static String digestSHA(final String src, final String algorithmName) throws Exception{
		String ret = "";
		if(src != null && !src.trim().equals("")) {
			MessageDigest digest = MessageDigest.getInstance(algorithmName);
            byte[] hash = digest.digest(src.getBytes());
            ret = Base64.encodeBase64URLSafeString(hash);
		}
		return ret;
	}

	/**
	 *@Title: getOutStorageCodeStatus
	 *@Description: TODO()
	 *@return Integer
	 *@author youjun
	 *@date 2017年8月13日 下午6:26:40
	 *@param channelType
	 *@return
	 */
	public static Integer getOutStorageCodeStatus(final Short channelType) {

		if(channelType==null) {
			return -1;
		}
		int status = 0;
		switch (channelType) {
		case Cons.OUT_STORAGE_CHANNEL_TYPE_SALES:
			status = MultistageLevelQRCodeStatusEnum.SALES_OUT_STORAGE.getId();
			break;
		case Cons.OUT_STORAGE_CHANNEL_TYPE_REWORK:
			status = MultistageLevelQRCodeStatusEnum.REWORK_OUT_STORAGE.getId();
			break;
		case Cons.OUT_STORAGE_CHANNEL_TYPE_TRANSFERS:
			status = MultistageLevelQRCodeStatusEnum.TRANSFERS_OUT_STORAGE.getId();
			break;
		case Cons.OUT_STORAGE_CHANNEL_TYPE_OTHER:
			status = MultistageLevelQRCodeStatusEnum.OTHER_OUT_STORAGE.getId();
			break;
		default:
			break;
		}
		return status;
	}
	
	/**
	 *@Title: classificationOutByBatch
	 *@Description: 根据产品、批次分组已出库单品码和包装单位码,返回map,key为批次号,value[]为{出库单品数量,出库包装数量}
	 *@return Map<String,Integer []>
	 *@author youjun
	 *@date 2017年8月13日 下午2:40:11
	 *@param singleLevelCodeList
	 *@param packLevelCodeList
	 *@param productId
	 *@return
	 * @throws ServiceException 
	 */
	public static Map<String, Integer[]> classificationOutOrInByBatch(final List<FirstLevelQRCode> singleLevelCodeList,
			final List<MultistageLevelQRCode> packLevelCodeList, final int productId) throws ServiceException {
		
		// 不能同时为空（同时为空,说明一个码也没出）
		if(CollectionUtils.isEmpty(singleLevelCodeList)&&CollectionUtils.isEmpty(packLevelCodeList)) {
			throw new ServiceException("参数有误");
		}
		final Map<String, Integer[]> map = new HashMap<String, Integer[]>();
		// 先取出产品
		if(!CollectionUtils.isEmpty(singleLevelCodeList)) {
			for(final FirstLevelQRCode firstItem:singleLevelCodeList) {
				if(firstItem.getProductId()==productId) {
					final String batchCode = firstItem.getBatchCode();
					if(map.containsKey(batchCode)){
						final Integer[] nums = map.get(batchCode);
						final Integer[] tempNums = new Integer[]{nums[0]+1, nums[1]};
						map.put(batchCode, tempNums); // 放入新的
					}else{
						map.put(batchCode, new Integer[]{1, 0});
					}
				}
			}
		}
		if(!CollectionUtils.isEmpty(packLevelCodeList)) {
			for(final MultistageLevelQRCode multisItem:packLevelCodeList) {
				if(multisItem.getProductId()==productId) {
					final String batchCode = multisItem.getBatchCode();
					if(map.containsKey(batchCode)){
						final Integer[] nums = map.get(batchCode);
						final Integer[] tempNums = new Integer[]{nums[0], nums[1]+1};
						map.put(batchCode, tempNums); // 放入新的
					}else{
						map.put(batchCode, new Integer[]{0, 1});
					}
				}
			}
		}
		return map;
	}
	
	/**
	 *@Title: generatedCode
	 *@Description: 生成码,prefix+15位数字
	 *@return String
	 *@author youjun
	 *@date 2017年8月20日 下午6:02:36
	 *@param prefix
	 *@return
	 */
	public static String generatedCode(final String prefix) {
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if(hashCodeV < 0) {//有可能是负数
            hashCodeV = - hashCodeV;
        }
        // 0 代表前面补充0     
        // 15 代表长度为15     
        // d 代表参数为正数型
        return prefix+String.format("%015d", hashCodeV);
    }
	
	public static void main(String[] args) throws Exception {
//		String xiangCode = "HTTP://TCC.SO/A/R*HF:2UAA1LW+Q.HGVCQL1?P=fl101";
		String xiangCode = "ZF$M48RRIYJAVJ0YHI:6ZC";
		System.out.println(conversionQRCode(xiangCode, true));
	}

	public static List<String> classificationByProductIdAndBatch(final List<MultistageLevelQRCode> packLevelCodeList,
			int productId, String batchCode) {

		batchCode = StringUtils.isNotBlank(batchCode)?batchCode:"";
		if(!CollectionUtils.isEmpty(packLevelCodeList)) {
			final List<String> boxList = new ArrayList<String>();
			for(final MultistageLevelQRCode item:packLevelCodeList) {
				final String batchCodeItem = StringUtils.isNotBlank(item.getBatchCode())?item.getBatchCode():"";
				if(batchCodeItem.equals(batchCode)) {
					boxList.add(item.getPackContent());
				}
			}
			return boxList;
		}
		return null;
	}

	/**
	 *@Title: classificationByProductId
	 *@Description: 从出入库的包装码集合中按产品找出对应的包装码
	 *@return List<String>
	 *@author youjun
	 *@date 2017年8月27日 下午9:43:02
	 *@param inPackLevelCodeList
	 *@param productId
	 *@return
	 */
	public static List<String> classificationByProductId(final List<MultistageLevelQRCode> packLevelCodeList, 
			final List<FirstLevelQRCode> singleLevelCodeList, int productId) {

		if(!CollectionUtils.isEmpty(packLevelCodeList)) {
			final List<String> boxList = new ArrayList<String>();
			for(final MultistageLevelQRCode item:packLevelCodeList) {
				if(item.getProductId().intValue()==productId) {
					boxList.add(item.getPackContent());
				}
			}
			return boxList;
		}
		/*if(!CollectionUtils.isEmpty(singleLevelCodeList)) {
			final List<String> singleList = new ArrayList<String>();
			for(final MultistageLevelQRCode item:packLevelCodeList) {
				if(item.getProductId().intValue()==productId) {
					singleList.add(item.getPackContent());
				}
			}
			return singleList;
		}*/
		
		if(!CollectionUtils.isEmpty(singleLevelCodeList)) {
			final List<String> singleList = new ArrayList<String>();
			for(final FirstLevelQRCode item:singleLevelCodeList) {
				if(item.getProductId().intValue()==productId) {
					singleList.add(item.getQrCode());
				}
			}
			return singleList;
		}
		return null;
	}
}
